package com.heima.admin.service.impl;

import com.baomidou.mybatisplus.core.toolkit.Wrappers;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.heima.admin.mapper.AdUserMapper;
import com.heima.admin.service.AdUserLoginService;
import com.heima.common.exception.CustException;
import com.heima.model.admin.dtos.AdUserDto;
import com.heima.model.admin.pojos.AdUser;
import com.heima.model.common.constants.AdminConstants;
import com.heima.model.common.dtos.ResponseResult;
import com.heima.model.common.enums.AppHttpCodeEnum;
import com.heima.utils.common.AppJwtUtil;
import org.apache.commons.lang3.StringUtils;
import org.springframework.stereotype.Service;
import org.springframework.util.DigestUtils;

import java.util.Date;
import java.util.HashMap;
import java.util.UUID;

//用户服务服务层
@Service
public class AdUserLoginServiceImpl extends ServiceImpl<AdUserMapper, AdUser> implements AdUserLoginService {

    @Override
    public ResponseResult login(AdUserDto dto) {
        //1.判断参数是否为空====================================
        //判断传来的 对象是否为空               用户名是否为空                           密码是否为空。
        if (dto==null || StringUtils.isBlank(dto.getName()) ||StringUtils.isBlank(dto.getPassword())){
            return ResponseResult.errorResult(AppHttpCodeEnum.PARAM_INVALID);
        }

        //2.登录校验===========================================
        //2.1 根据用户名 精确查询 判断 用户 是否存在
        AdUser aduser = getOne(Wrappers.<AdUser>lambdaQuery()
                .eq(AdUser::getName,dto.getName())
                .eq(AdUser::getStatus, AdminConstants.AD_USER_ISSTATUS)
        );
        //2.2 判断是否存在 此用户
        if (aduser==null){                    //2.3 返回前端 用户名 或者 密码 不存在
            CustException.cust(AppHttpCodeEnum.DATA_NOT_EXIST);
        }

        //3.当用户存在时；判断密码是否 一致=============================
        //3.1 获取 dto和db 的密码
        //前端传来的密码
        String dtoPassword = dto.getPassword();
        //数据库中查询出来的密码
        String dbpassword = aduser.getPassword();
        //数据库中查询出来的 加密 需要的 salt
        String salt = aduser.getSalt();
        //3.2 通过加密规则 判断 加密后 两者是否相同
        //加密规则 pwd+salt
        String saltpwd=dtoPassword+salt; //拼接 dto+salt
        String md5dto = DigestUtils.md5DigestAsHex(saltpwd.getBytes());//md5 编译后的 密码
        if (!dbpassword.equals(md5dto)){
            //如果 不相同的话 返回前端 账户 或者 密码 有误
            return ResponseResult.errorResult(AppHttpCodeEnum.ADMIN_USER_NAMEORPWD_ERROR);
        }

        //4.根据数据库数据库登录时间
        aduser.setLoginTime(new Date());
        updateById(aduser); //调用mybatiesPlus 的修改方法

        //5. 返回结果 生成 token
        //5.1 创建 map集合 存放 要返回 前端的AdUser和 token信息
        HashMap<String, Object> map = new HashMap<>();
        //5.2 使用工具包 获取 token 信息
        String token = AppJwtUtil.getToken(aduser.getId().longValue());
        //5.3 将 Aduser 的 password 和 salt 清空
        aduser.setPassword(null);
        aduser.setSalt(null);

        //5.3 往map中 添加数据
        map.put("token",token);
        map.put("user",aduser);

        //6.响应结果
        return ResponseResult.okResult(map);
    }

    //用户注册方法
    @Override
    public ResponseResult register(AdUser user) {
        //1.判断 参数是否 合法
        if (user==null ||StringUtils.isEmpty(user.getName()) || StringUtils.isEmpty(user.getPassword())){
            //提示 用户名 和 密码 不能为空
            return ResponseResult.errorResult(AppHttpCodeEnum.ADMIN_USER_NAMEORPWD_ERROR);
        }
        //2.根据新增 用户名 精确查询 判断 用户 是否  已经存在
        String userName = user.getName();
        //2.1 根据name查询
        AdUser adUser =getOne(Wrappers.<AdUser>lambdaQuery()
            .eq(AdUser::getName,userName)
        );
        //2.2 判断用户是否为空
        if ( adUser!=null){
            //不为空 提醒 用户 用户已存在
            return ResponseResult.errorResult(AppHttpCodeEnum.ADMIN_USER_NAMEORPWD_ERROR);
        }

        //3.注册 用户 将 密码 通过 md5 进行 加密
        //3.1 uuid 随机生成数字 并且 将 - 替换为空格
        String salt = UUID.randomUUID().toString().replaceAll("-", "");
        //3.2 将 password 和 salt 拼接
        String password = user.getPassword();
        String saltPWD =password+salt;
        //3.3 md5 加密密码
        String s = DigestUtils.md5DigestAsHex(saltPWD.getBytes());
        System.out.println("加盐后的密码为 = " + s);

        //4.封装 数据
        user.setSalt(salt); //盐
        user.setPassword(s);  //密码
        user.setCreatedTime(new Date()); //创建日期
        user.setStatus(AdminConstants.AD_USER_ISSTATUS); //账号状态 9 为 可用

        //5.添加数据
        save(user);

        //6.响应结果
        return ResponseResult.okResult(AppHttpCodeEnum.SUCCESS);
    }
}
